#include "entitymanager.h"
#include <QDebug>

EntityManager::EntityManager(QObject *parent) : QObject(parent)
{
}

EntityManager::~EntityManager()
{
    foreach (Entity *entity, mEntities.values()) {
        entity->deleteLater();
    }
}

EntityList EntityManager::entities()
{
    return mEntities.values();
}

Entity* EntityManager::getEntity(const int &id)
{
    if(id != -1)
        return mEntities.value(id);
    else
        return nullptr;
}

void EntityManager::addEntity(Entity *entiy)
{
    if(entiy->id() != -1 && mEntities.contains(entiy->id())) {
        qDebug() << "dplicate id " << entiy << mEntities.value(entiy->id());
        return;
    }

    if(entiy->id() != -1 && !mEntities.contains(entiy->id())){
        mEntities.insert(entiy->id(), entiy);
        emit entityAdded(entiy);
    } else{
        int id = -1;
        for(int i = 0; i < mMaxID; i++) {
            if (mEntities.contains(i))
                continue;
            id = i;
            break;
        }
        if (id == -1) {
            id = mMaxID + 1;
        }
        entiy->setID(id);
        mMaxID = qMax(mMaxID, id);

        mEntities.insert(id, entiy);
        emit entityAdded(entiy);
    }

    connect(entiy, &Entity::destroyed, this, &EntityManager::onEntityDestroyed);
}

void EntityManager::addSubEntity(Entity *entiy)
{
    if(entiy->id() != -1 && mEntities.contains(entiy->id())) {
        qDebug() << "dplicate id " << entiy << mEntities.value(entiy->id());
        return;
    }

    if(entiy->id() != -1 && !mEntities.contains(entiy->id())){
        mEntities.insert(entiy->id(), entiy);
    } else{
        int id = -1;
        for(int i = 0; i < mMaxID; i++) {
            if (mEntities.contains(i))
                continue;
            id = i;
            break;
        }
        if (id == -1) {
            id = mMaxID + 1;
        }
        entiy->setID(id);
        mMaxID = qMax(mMaxID, id);

        mEntities.insert(id, entiy);
    }

    connect(entiy, &Entity::destroyed, this, &EntityManager::onEntityDestroyed);
}

void EntityManager::clearEntities()
{
    mEntities.clear();
    emit entityCleared();
}

void EntityManager::tick(const int &msec)
{
    foreach(Entity* e, mEntities.values()) {
        e->tick(msec);
    }
}

void EntityManager::onEntityDestroyed()
{
    Entity* e = static_cast<Entity*>(sender());
    if (e)
        mEntities.take(e->id());
}
